package com.todo.user.application.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.todo.common.common.enums.BizErrorCodeEnum;
import com.todo.common.common.exception.BizException;
import com.todo.common.utils.StringUtils;
import com.todo.user.application.convert.UserServiceConvert;
import com.todo.user.application.entity.bo.UserInfoDetailBO;
import com.todo.user.application.entity.bo.UserSimplyInfoBO;
import com.todo.user.application.service.UserCacheService;
import com.todo.user.application.service.UserInfoService;
import com.todo.user.infrastructure.entity.domain.UserAccountDO;
import com.todo.user.infrastructure.repository.UserAccountRepository;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author zhangwenxiang
 * @date 2024/4/7 21:36
 * @description
 */
@Slf4j
@Service
public class UserInfoServiceImpl implements UserInfoService {

    public static final int DEFAULT_MAX_QUERY_SIZE = 100;

    @Resource
    private UserAccountRepository userAccountRepository;
    @Resource
    private UserCacheService userCacheService;

    @Override
    public Boolean updateUserInfoDetail(UserInfoDetailBO userInfoDetailBO) {
        if (userInfoDetailBO == null || userInfoDetailBO.getUserId() == null) {
            throw new BizException(BizErrorCodeEnum.PARAM_ERROR);
        }
        UserAccountDO userAccountDO = UserServiceConvert.convertToUserAccountDO(userInfoDetailBO);
        Boolean updateResult = userAccountRepository.updateUserAccountById(userAccountDO);
        log.info("UserInfoService#UpdateUserInfoDetail 更新用户信息详情完成 userInfoDetailBO：【{}】", JSONObject.toJSONString(userInfoDetailBO));
        if (updateResult) {
            userCacheService.removeUserInfoDetail(userInfoDetailBO.getUserId());
        }
        return updateResult;
    }

    @Override
    public UserInfoDetailBO queryUserInfoDetailById(Long userId) {
        if (userId == null || userId < 0) {
            return null;
        }
        UserInfoDetailBO userInfoDetail = userCacheService.getUserInfoDetail(userId);
        if (userInfoDetail != null) {
            return userInfoDetail;
        }

        UserAccountDO userAccountDO = userAccountRepository.queryUserInfoById(userId);
        if (userAccountDO == null) {
            log.info("UserInfoService#queryUserInfoDetailById 根据用户Id查询用户详情完成，数据为空，不存在用户记录 userId：【{}】", userId);
            return null;
        }
        UserInfoDetailBO userInfoDetailBO = UserServiceConvert.convertToUserInfoDetailBO(userAccountDO);
        log.info("UserInfoService#queryUserInfoDetailById 根据用户id查询用户详情信息完成 userId：【{}】userInfoDetailBO:【{}】", userId, JSONObject.toJSONString(userInfoDetailBO));
        userCacheService.setUserInfoDetail(userInfoDetailBO);
        return userInfoDetailBO;
    }

    public List<UserInfoDetailBO> queryUserInfoDetailByIdList(List<Long> userIdList) {
        if (CollectionUtils.isEmpty(userIdList)) {
            return Lists.newArrayList();
        }
        if (userIdList.size() > DEFAULT_MAX_QUERY_SIZE) {
            log.error("UserInfoService#queryUserInfoDetailByIdList 查询数量超限，最大支持{}用户查询，当前查询量为：{}", DEFAULT_MAX_QUERY_SIZE, userIdList.size());
            throw new BizException(BizErrorCodeEnum.QUANTITY_EXPLOSION);
        }
        List<UserInfoDetailBO> result = new ArrayList<>();
        List<Long> failedCacheUserId = new ArrayList<>();
        for (Long userId : userIdList) {
            UserInfoDetailBO userInfoDetail = userCacheService.getUserInfoDetail(userId);
            if (userInfoDetail == null) {
                failedCacheUserId.add(userId);
                continue;
            }
            result.add(userInfoDetail);
        }
        //缓存查询失败数据查询db进行填充
        if (CollectionUtils.isNotEmpty(failedCacheUserId)) {
            List<UserAccountDO> userAccountDOList = userAccountRepository.queryUserInfoByIdList(failedCacheUserId);
            if (CollectionUtils.isEmpty(userAccountDOList)) {
                return result;
            }

            log.info("UserInfoService#queryUserInfoDetailByIdList 缓存查询失败用户数据查询完成 failedCacheUserId：【{}】", JSONObject.toJSONString(failedCacheUserId));
            for (UserAccountDO userAccountDO : userAccountDOList) {
                UserInfoDetailBO userInfoDetailBO = UserServiceConvert.convertToUserInfoDetailBO(userAccountDO);
                userCacheService.setUserInfoDetail(userInfoDetailBO);
                result.add(userInfoDetailBO);
            }
        }

        return result;
    }

    @Override
    public UserSimplyInfoBO querySimplyUserInfoById(Long userId) {
        if (userId == null || userId < 0) {
            return null;
        }
        List<UserSimplyInfoBO> userSimplyInfoBOS = batchQuerySimplyUserInfo(Collections.singletonList(userId));
        if (CollectionUtils.isEmpty(userSimplyInfoBOS)) {
            return null;
        }
        return userSimplyInfoBOS.get(0);
    }

    @Override
    public List<UserSimplyInfoBO> batchQuerySimplyUserInfo(List<Long> userIdList) {
        if (CollectionUtils.isEmpty(userIdList)) {
            return Collections.emptyList();
        }
        List<UserInfoDetailBO> userInfoDetailBOS = queryUserInfoDetailByIdList(userIdList);
        if (CollectionUtils.isEmpty(userInfoDetailBOS)) {
            return Collections.emptyList();
        }
        Map<Long, UserInfoDetailBO> userInfoDetailBOMap = userInfoDetailBOS
                .stream()
                .collect(Collectors.toMap(UserInfoDetailBO::getUserId, userInfoDetailBO -> userInfoDetailBO, (k1, k2) -> k1));
        List<UserSimplyInfoBO> result = new ArrayList<>();
        for (Long userId : userIdList) {
            UserInfoDetailBO userInfoDetailBO = userInfoDetailBOMap.get(userId);
            if (userInfoDetailBO == null) {
                continue;
            }
            UserSimplyInfoBO userSimplyInfoBO = new UserSimplyInfoBO();
            userSimplyInfoBO.setUserId(userInfoDetailBO.getUserId());
            userSimplyInfoBO.setUserName(userInfoDetailBO.getUserName());
            userSimplyInfoBO.setNickName(userInfoDetailBO.getNickName());
            userSimplyInfoBO.setGender(userInfoDetailBO.getGender());
            userSimplyInfoBO.setLocation(userInfoDetailBO.getLocation());
            userSimplyInfoBO.setHeadImg(userInfoDetailBO.getHeadImg());
            result.add(userSimplyInfoBO);
        }
        return result;
    }

    @Override
    public Boolean updateUserHeadImg(Long userId, String headImg) {
        if (userId == null || StringUtils.isBlank(headImg)) {
            throw new BizException(BizErrorCodeEnum.PARAM_ERROR);
        }
        UserInfoDetailBO userInfoDetailBO = queryUserInfoDetailById(userId);
        if (userInfoDetailBO == null) {
            throw new BizException(BizErrorCodeEnum.USER_DOES_NOT_EXISTS);
        }
        userInfoDetailBO.setHeadImg(headImg);
        Boolean updateResult = updateUserInfoDetail(userInfoDetailBO);
        //TODO 照片图片审核
        return updateResult;
    }

}
